package application

import (
	ai "chatbot-api-go/domain/ai/api"
	"chatbot-api-go/domain/zsxq/api"
	"chatbot-api-go/global"
	"encoding/base64"
	"github.com/robfig/cron/v3"
	"go.uber.org/zap"
	"math/rand"
	"time"
)

type boolgen struct {
	src       rand.Source
	cache     int64
	remaining int
}

func Run() {
	// 新建一个定时任务对象
	// 根据cron表达式进行时间调度，cron可以精确到秒，大部分表达式格式也是从秒开始。
	//crontab := cron.New()  默认从分开始进行时间调度
	crontab := cron.New(cron.WithSeconds()) //精确到秒

	task := func() {
		// 生成随机bool值，随机打烊
		r := New()
		if r.Bool() {
			zap.S().Infof(`%s随机打烊中..`, global.ServerConfig.ChatBotInfo.GroupInfo.GroupName)
		}
		now := time.Now().Hour()
		if now > 22 && now < 7 {
			zap.S().Infof("%s打烊时间不工作，AI 下班了！", global.ServerConfig.ChatBotInfo.GroupInfo.GroupName)
		}
		// 检索问题
		questions, err := api.QueryUnAnsweredQuestionsTopicId(global.ServerConfig.ChatBotInfo.GroupInfo.GroupId, global.ServerConfig.ChatBotInfo.GroupInfo.Cookie)

		if err != nil {
			zap.S().Errorw("【CronTask】获取题目列表失败",
				"msg",
				err.Error(),
			)
			return
		}
		if len(questions.RespData.Topics) == 0 {
			zap.S().Infof("%s 本次检索未查询到待会答问题", global.ServerConfig.ChatBotInfo.GroupInfo.GroupName)
			return
		}

		// Ai回答
		topic := questions.RespData.Topics[len(questions.RespData.Topics)-1]
		res, err := ai.DoChatGPT(global.ServerConfig.ChatBotInfo.GroupInfo.OpenAiKey, topic.Question.Text)

		if err != nil {
			zap.S().Errorw("【CronTask】ChatGPT回答异常，稍后重试",
				"msg",
				err.Error(),
			)
		}

		// 问题回复
		status, err := api.Answer(global.ServerConfig.ChatBotInfo.GroupInfo.GroupId,
			global.ServerConfig.ChatBotInfo.GroupInfo.Cookie,
			topic.TopicId,
			res,
			global.ServerConfig.ChatBotInfo.GroupInfo.Silenced,
		)

		zap.S().Infof("%s 编号：%d 问题：%s 回答：%s 状态：%b",
			global.ServerConfig.ChatBotInfo.GroupInfo.GroupName,
			topic.TopicId,
			topic.Question.Text,
			res,
			status)

	}
	spec, err := base64.StdEncoding.DecodeString(global.ServerConfig.ChatBotInfo.GroupInfo.CronExpression)
	if err != nil {
		zap.S().Errorw("【CronTask】定时器读取异常，稍后重试",
			"msg",
			err.Error(),
		)
	}
	//定时任务
	//spec := "*/5 * * * * ?" //cron表达式，每五秒一次
	// 添加定时任务,
	crontab.AddFunc(string(spec), task)
	// 启动定时器
	crontab.Start()

}

func (b *boolgen) Bool() bool {
	if b.remaining == 0 {
		b.cache, b.remaining = b.src.Int63(), 63
	}

	result := b.cache&0x01 == 1
	b.cache >>= 1
	b.remaining--

	return result
}

func New() *boolgen {
	return &boolgen{src: rand.NewSource(time.Now().UnixNano())}
}
